; ***********************

(setq *medrules* '(


;Medical Inference

(=>	(and 	(body-part ?Patient ?BodyPart)
			(bleeding-at ?Injury ?BodyPart))

(has-untreated-injury ?Patient ?Injury))


(=>	(has-untreated-injury ?Patient ?SomeInjury) 

(injured ?Patient))

(=>	(and	(injury ?Injury)
			(bleeding ?Injury) 
			(injury-at-bodypart ?Injury ?BodyPart))

(bleeding-at ?Injury ?BodyPart))


(=>	(and	(location ?Injury  ?InjuryLocation)
			(injury-at-bodypart ?Injury ?BodyPart)		
			(higher-joint ?BodyPart ?Joint)					
			(injury-at-bodypart  ?Joint  ?JointLocation)					
			(below ?InjuryLocation  ?TourniquetLocation)
			(below ?TourniquetLocation ?JointLocation))
			(tourniquet-position ?Injury ?TourniquetLocation))


(=>	(and	(criticality ?Injury1 ?c1)
			(criticality ?Injury2 ?c2)
			(> ?c1 ?c2 ))

(injury-worse-than ?Injury1 ?Injury2))


; removed because potential problems with negated conditions
; (=>	(not (patient-injury-worst-than ?Patient ?OtherInjury ?Injury))

; (worst-untreated-injury ?Patient ?Injury))


; (=> (and 	(has-untreated-injury ?Patient  ?Injury1)
			; (has-untreated-injury ?Patient  ?Injury2)	
			; (\= ?OtherInjury  Injury)
			; (injury-worse-than ?Injury1 ?Injury2))

; (patient-injury-worst-than ?Patient ?Injury1 ?Injury2))


;;;; Goal Concepts

(=>	(stabilized-injuries ?Person)

(stabilized-patient ?Person))
	; we may add a conjuction for other conditions here

(=>	(not (has-untreated-injury ?Person ?SomeInjury))

(stabilized-injuries ?Person))

;S10 	

(=>	(and	(has-untreated-injury ?Patient ?Injury)
			(not (has-multiple-untreated-injuries ?Patient)))

(has-one-untreated-injury ?Patient ?Injury))

;S11 	 

(=>	(and	((has-untreated-injury ?Patient ?Injury1)
			 (has-untreated-injury ?Patient ?Injury2)
			 (\= ?Injury1 ?Injury2)))

(has-multiple-untreated-injuries ?Patient))

;S12 

(=>	(not (has-untreated-injury ?Person ?SomeInjury))

(stabilized-injuries ?Person))

;;;; Intentions


(=>	(and	(goal  (stabilized-patient ?Patient))
			(injured ?Patient)
			(intention  (stabilize-injuries ?Patient)))

(intention (stabilize-patient ?Patient)))


; MULTIPLE INJURY VERSION
(=>	(and	(has-untreated-injury ?Patient ?Injury)
			(worst-untreated-injury ?Patient ?Injury)
			(intention (stabilize-injury ?Injury)) 
			(goal (stabilized-injuries ?Patient)))

(intention (stabilize-injuries ?Patient))) 


; SIMPLIFIED TWO INJURY VERSION
; there is a potential problem here. Since we don't have time stamps
; we don't distinguish between completed and noncompleted intensions. Therefore, worse-than really 
; does not help in this case.

(=>	(and	(has-untreated-injury ?Patient ?Injury1)
		    (has-untreated-injury ?Patient ?Injury2)
			(injury-worse-than ?Injury1 ?Injury2)
			(intention (stabilize-injury ?Injury1)) 
			(intention (stabilize-injury ?Injury2)) 
			(goal (stabilized-injuries ?Patient)))
			; if intentions had ids, we could have here that says something about their temporal order.
			
(intention (stabilize-injuries ?Patient))) 



; this is a reactive skill. It handles multiple intentions by reconstructing the explanation for each injury. A recursive version may be better for a temporal explanation.

(=>	(and	(bleeding ?Injury)
			(item-available ?Item )
			(tourniquet ?Item)
			(intention (stop-bleeding-with ?Injury ?Item))
			(goal (stabilized-injury ?Injury)))

		(intention (stabilize-injury ?Injury))) 


(=>	(and	(item-available ?Item )
			(tourniquet ?Item)
			(bleeding ?Injury)
			(tourniquet-position ?InjuryLocation ?TourniquettLocation)
			(intention ( position-tourniquet ?Injury ?Item ?TourniquettLocation))
			(intention ( turn-tourniquet ?Injury ?Item))
			(goal (not (bleeding ?Injury))))

(intention (stop-bleeding-with ?Injury ?Item))) 

)) ; END OF RULES
	
; ******************** TRACE *************************
	
	

; State 1
; We have a man down.

(setq *s1*
	'((person patient1)
	  (injured patient1)))

; State 2
; Where is the injury?
; A mine went off. 
; He is bleeding from the left leg and torso.

(setq *s2*
	'((mine mine1)
	  (exploded mine1)

	  (body-part patient1 bodypart1)
	  (left-leg patient1 bodypart1)
	  (body-part patient1 bodypart2)
	  (torso patient1 bodypart2)

	  (injury injury1)			; this is an object 
	  (bleeding injury1) 		; this is an unary property, not a object
	  (injury-at-bodypart injury1 bodypart1)

	  (injury injury2)
	  (bleeding injury2) 
	  (injury-at-bodypart injury2 bodypart2 )))
	  

;State 3
; C: How bad is the bleeding?
; M: The leg is much worse.
(setq *s3*
	'( (injury-worse-than injury1 injury2) ))

; State 4 
; C: Okay, use a tourniquet to stop the bleeding.

(setq *s4*
	'((intention  (stop-bleeding injury1 tourniquet1))
	  (tourniquet tourniquet1)))

;State 5 
; M: Right, where shall I put it?
; C: Just below the joint above the wound.
; Keep turning until it stops bleeding.
; Input State

(setq *s5*
	'((intention ( position-tourniquet injury1 tourniquet1 location3))
	  (location injury1 location1)
	  (higher-joint bodypart1 joint1)
	  (injury-at-bodypart joint location2)
	  (below location3 location2)
	  (below location1 location3)

	  (intention ( turn-tourniquet  injury1  tourniquet1))
	  ;(goal (not (bleeding injury1)))
))
		; In the dialog the goal is presented in relation to the skill, but we ignored this for now.

; State 6
;M: Okay, the bleeding stopped.
; It is not clear here what the medic means. We probably need to specify clearly that the leg bleeding has stopped. 

(setq *s6*
	'((not (bleeding injury1))))

(setq *sfull* (funcall #'append *s1* *s2* *s3* *s4* *s5* *s6*))

;; initialize a new test case based on the 
;; plan recognition example from Ng's thesis.
(defun test-med (steps 
		&optional (example *sfull*) (pick-belief #'pick-belief-random)) 
  (initialize)
  ;; for plan recognition, we're basically following a single narrative.
  (add-sensor 'story wm)

  ;; build long-term memory.
;  (dolist (r (list *rule1*)) (store-rule r kb))
  (dolist (r *medrules*) (store-rule r kb))
  ;; (dolist (r *sort-hierarchy*) (store-rule r kb))

  (add-facts example 'story wm)

  (dotimes (i steps) (infer wm kb :bc-only? nil
			    :focused? nil :p -1
			    :pick-belief pick-belief))


  (format t "~%Observations:~%")
  (dolist (i (get-observed-beliefs (wm-prime wm)))
    (format t "~T~A~%" (second i)))

  (format t "Assumptions:~%")
  (dolist (i (get-local-beliefs (wm-prime wm)))
    (format t "~T~A~%" (second i)))

  (format t "Goals:~%")
  (dolist (i (get-goals (wm-prime wm)))
    (format t "~T~A~%" (second i)))

  (format t "Intentions:~%")
  (dolist (i (get-intentions (wm-prime wm)))
    (format t "~T~A~%" (second i)))
  

  (dolist (i (get-justifications (wm-prime wm)))
    (format t "~%~%~A supports: ~A" (justification-id i) 
	    (sort (mapcar #'(lambda (x) (belief-id (second x))) (get-supported-beliefs i (wm-prime wm)))
		  #'string< :key #'symbol-name))
        (pprint  i))

  (output-dot wm))

(defun inc-test-med (steps &optional (example *s1*) 
		    (plot? t) (pick-belief #'pick-belief-random)) 

  (initialize)

  ;; for plan recognition, we're basically following a single narrative.
  (add-sensor 'story wm)

  ;; build long-term memory.
  (dolist (r *medrules*) (store-rule r kb))
  ;; (dolist (r *sort-hierarchy*) (store-rule r kb))

  (add-facts (list (car example)) 'story wm)
  (dotimes (i steps) (infer wm kb :bc-only? nil
			    :focused? nil :p -1
			    :pick-belief pick-belief))
  
  (dolist (f (cdr example))
    (add-facts (list f) 'story wm)
    (dotimes (i steps) (infer wm kb :bc-only? nil
			    :focused? nil :p -1
			    :pick-belief pick-belief))
    (when plot?
      (output-dot wm)
      (sleep 1))))



#|
(setq *buggy* '((=>	(and	(injury ?Injury)
			 (bleeding ?Injury) 
			 (injury-at-bodypart ?Injury ?BodyPart))
		 
		 (bleeding-at ?Injury ?BodyPart))
		
		(=>	(and	(item-available ?Item )
			 (tourniquet ?Item)
			 (bleeding ?Injury)
			 (tourniquet-position ?InjuryLocation ?TourniquettLocation)
			 (intention ( position-tourniquet ?Injury ?Item ?TourniquettLocation))
			 (intention ( turn-tourniquet ?Injury ?Item))
			 (goal (not (bleeding ?Injury))))
		 
		 (intention (stop-bleeding-with ?Injury ?Item)))
		))



(defun bug-test ()
  (setq *medrules* *buggy*)

  (initialize)
  (add-sensor 'story wm)
  (dolist (r *medrules*) (store-rule r kb))
  (add-facts *sfull*  'story wm)

  (infer wm kb :pick-belief #'(lambda (x &key world)  (list (wm-prime wm) (get-local-belief 'b10 (get-world 'story wm)))))
  (format t "~%~A~%" (get-justifications (wm-prime wm)))
  (infer wm kb :pick-belief #'(lambda (x &key world)  (list (wm-prime wm) (get-local-belief 'b17 (get-world 'story wm)))))
  (format t "~%~A~%" (get-justifications (wm-prime wm))))
|#